/**
 * 
 */
package com.itboye.allshengmedical.sci.cmd.resp;

import java.util.Locale;

import android.R.bool;
import android.util.Log;

import com.example.allshengmedical.experimentnew.view.IFileManagerView;
import com.itboye.allshengmedical.sci.HexHelper;

/**
 * @modify 2017-05-27 重构了寻找有效数据串的算法
 * @author 贝贝 346551990@qq.com
 * @date 2016-12-8
 */
public class RespDataHelper {

	final String tag = "serial";

	private int dataLength;// 数据长度*2=字符串长度
	private String startFlag = "5AA5";// 起始标记位
	private String endFlag = "3EE3";// 结束标志位

	private boolean readContent = false;// 是否正在读取内容
	private boolean isFindOnePack = false;// 是否找到一个包
	private StringBuilder builder;

	private String lastHexData;// 上一次的获取的数据

	private static RespDataHelper helperInstance;
	String content = "";
	
	public String getBuilderString(){
		return builder.toString();
	}
	public void clearBuilderString(){
		builder.setLength(0);
	}

	public static synchronized RespDataHelper getInstance() {
		if (helperInstance == null) {
			helperInstance = new RespDataHelper();
		}

		return helperInstance;
	}

	private RespDataHelper() {
		this.builder = new StringBuilder();
		this.readContent = false;
		this.dataLength = 0;
		this.isFindOnePack = false;
		this.lastHexData = "";
	}

	/**
	 * 压入数据
	 * 
	 * @param hex
	 * @return
	 */

	public String push(String hex) {

		this.isFindOnePack = false;
		hex = hex.toUpperCase(Locale.CHINA);

		Log.d(tag, "压入十六进制字符串数据=" + hex);
		if (isReadingContent()) {
			Log.d(tag, "读取内容数据中...");
			// 读取数据内容
			this.appendContentOrEnd(hex);

		} else {

			Log.d(tag, "寻找起始标志位...");
			// 寻找起始标志位
			this.findStartFlag(hex);
		}

		if (!isFindOnePack()) {
			this.lastHexData = "";
		}

		return this.lastHexData;
	}

	/**
	 * 追加内容或着找到结束标记位
	 * 
	 * @param hex
	 */
	private void appendContentOrEnd(String hex) {

		//1. 寻找长度
		if(!this.isFindLengthFlag() && hex.length() >= 2){
			String len = hex.substring(0, 2);
			hex = hex.substring(2,hex.length());
			builder.append(len);
			Log.d(tag, "读取到数据长度十六进制=" + len);
			this.dataLength = HexHelper.toInt(len);
			Log.d(tag, "分析得到长度=" + this.dataLength);
		}else{
			Log.d(tag, "数据("+ hex +")非法,必须有起始位4位的5aa5、长度位2位");
			return ;
		}

		Log.d(tag, "目前读取到的字符串builder=" + builder.toString());
		//2. 前提条件已经满足，长度位置、起始位置都已经压入builder
		//3. 寻找结束标记位置 3EE3
		
		int endFlagIndex = -6;
		// 期望的结束位置下标 = 4位起始 + 2位长度 + 4位校验 + 数据内容长度*2
		int expectEndFlagIndex = this.dataLength * 2  + 4 + 2 + 4;
		int builderLength = builder.length();
		while(endFlagIndex != -1){
			Log.d(tag, "结束位置"+endFlagIndex);
			if(endFlagIndex + 6 > hex.length() - endFlag.length()){
				Log.d(tag, "该数据串没有保护结束标记"+hex);
				break;
			}
			// 读取 结束位置
			endFlagIndex = hex.substring(endFlagIndex + 6 , hex.length()).indexOf(endFlag);
			
			if(endFlagIndex != -1){

				Log.d(tag, "期望"+expectEndFlagIndex+",实际"+( builderLength + endFlagIndex));
				// 如果找到3ee3，并且满足长度要求
				if (expectEndFlagIndex == builderLength + endFlagIndex) {
		
					// 且已读取数据内容长度 刚好为期望的dataLength
					Log.d(tag, "找到结束位" + endFlagIndex);
					
					// 10 = 4位起始长度 + 2位数据长度 + 4位校验长度
					builder.append(hex.substring(0 , endFlagIndex + 4));
					this.lastHexData = builder.toString();
					Log.d(tag, "找到一个数据包=" + lastHexData);
					findOnePack();
					readContentOver();
					break;
				}else{
					
				}
			}else {
				// 如果没有找到
				builder.append(hex);
				if (builder.length() > 14 + this.dataLength*2) {
					// 超过读取数据内容
					Log.d(tag, "数据包长度过长");
					builder.setLength(0);
					this.readContentOver();
				}
			}

		}

	}

	/**
	 * 找到一个包
	 */
	private void findOnePack() {
		this.isFindOnePack = true;
	}

	/**
	 * 是否组成一个包
	 * 
	 * @return
	 */
	private boolean isFindOnePack() {
		return this.isFindOnePack == true;
	}

	/**
	 * 是否正在读取数据中...
	 */
	private boolean isReadingContent() {
		return this.readContent == true;
	}

	/**
	 * 结束读取数据内容
	 */
	private void readContentOver() {
		this.readContent = false;
	}

	/**
	 * 查找开始标记
	 * 
	 * @param hex
	 */
	private void findStartFlag(String hex) {

		if (this.isReadingContent()) {
			// 正在读取内容中，则直接返回，有可能数据中包含开始标记
			return;
		}

		if(hex.length() < startFlag.length()){
			builder.append(hex);//拼接
			return ;
		}
		int index = hex.indexOf(startFlag);
		
		Log.d(tag, "读取坐标位置" + index);

		if (index != -1) { 
			builder.setLength(0);
			builder.append(startFlag);//拼接起始位置
			
			this.lastHexData = "";
			
			appendContentOrEnd(hex.substring(index + startFlag.length(), hex.length()));

		} else {

			Log.d(tag,  "读取坐标位置失败");
		}
	}
	

	/**
	 * 是否找到起始标记
	 * @return
	 */
	public boolean isFindStartFlag(){
		if(builder.length() >= 4 && builder.substring(0,4).equalsIgnoreCase("5aa5")){
			return true;
		}
		return false;
	}
	
	/**
	 * 是否找到长度标记
	 * @return
	 */
	public boolean isFindLengthFlag(){
		if(isFindStartFlag() && builder.length() > 6){
			return true;
		}
		return false;
	}
	
	
}
